package grades

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strconv"
	"strings"
)

//放去注册的函数
func RegisterHandlers() {
	handler := new(studentsHandler)
	http.Handle("/students", handler)
	http.Handle("/students/", handler)
}

type studentsHandler struct {
}

// 获取/students
// 获取/students:{id}
// 获取/students:{id}/grades
func (sh studentsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	//通常参数是通过正则表达式去取
	pathSegments := strings.Split(r.URL.Path, "/")
	switch len(pathSegments) {
	case 2:
		sh.getAll(w, r)
	case 3:
		id, err := strconv.Atoi(pathSegments[2])
		if err != nil {
			w.WriteHeader(http.StatusNotFound)
			return
		}
		//mylog.ClientLog.Println(id)这就是一种用法，看你放在哪里了
		sh.getOne(w, r, id)
	case 4:
		id, err := strconv.Atoi(pathSegments[2])
		if err != nil {
			w.WriteHeader(http.StatusNotFound)
			return
		}
		sh.addGrade(w, r, id)
	default:
		w.WriteHeader(http.StatusNotFound)

	}

}

//实现toJson
func (sh studentsHandler) toJSON(obj interface{}) ([]byte, error) {
	var b bytes.Buffer
	enc := json.NewEncoder(&b)
	if err := enc.Encode(obj); err != nil {
		return nil, fmt.Errorf("Failed to serialize student(s): %q", err)

	}
	return b.Bytes(), nil
}

//实现getAll
func (sh studentsHandler) getAll(w http.ResponseWriter, r *http.Request) {
	studentsMutex.Lock()
	defer studentsMutex.Unlock()

	data, err := sh.toJSON(students)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		log.Println(err)
		return
	}
	w.Header().Add("Content-Type", "application/json")
	w.Write(data)
}

//实现getOne
func (sh studentsHandler) getOne(w http.ResponseWriter, r *http.Request, id int) {
	//锁
	studentsMutex.Lock()
	defer studentsMutex.Unlock()
	//获取student
	student, err := students.GetByID(id)
	if err != nil {
		w.WriteHeader(http.StatusNotFound)
		log.Println(err)
		return
	}
	//student序列化json
	data, err := sh.toJSON(student)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		log.Printf("Failed to serialize student: %q", err)
		return
	}
	w.Header().Add("Content-Type", "application/json")
	w.Write(data)

}

//实现addGrade,相应一个grade
func (sh studentsHandler) addGrade(w http.ResponseWriter, r *http.Request, id int) {
	//锁
	studentsMutex.Lock()
	defer studentsMutex.Unlock()
	//获取student
	student, err := students.GetByID(id)
	if err != nil {
		w.WriteHeader(http.StatusNotFound)
		log.Println(err)
		return
	}
	var g Grade
	dec := json.NewDecoder(r.Body)
	if err := dec.Decode(&g); err != nil {
		w.WriteHeader(http.StatusBadRequest)
		log.Println(err)
		return
	}
	//更新当前student的成绩列表
	student.Grades = append(student.Grades, g)
	//请求成功，服务器已经更新资源
	w.WriteHeader(http.StatusCreated)
	//student序列化json
	data, err := sh.toJSON(student)
	if err != nil {
		log.Println(err)
		return //序列化失败就不返回了，保留前面的201状态即可
	}
	w.Header().Add("Content-Type", "application/json")
	w.Write(data)
}
